﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using CommonClasses.Logger;

namespace CommonClasses.Utility
{

    #region Exception classes

    /// <summary>
    /// Исключение: ошибка загрузки проекта
    /// </summary>
    public class LoadingProjectException : Exception
    {
        public LoadingProjectException(string exceptionMessage) : base(exceptionMessage){}
    }

    /// <summary>
    /// Исключение: ошибка загрузки описания оборудования
    /// </summary>
    public class LoadingDomainModelException : Exception
    {
        public LoadingDomainModelException(string exceptionMessage) : base(exceptionMessage) { }
    }

    /// <summary>
    /// Исключение: ошибка совместимости с описанием оборудования
    /// </summary>
    public class LoadingDomainModelCorrespException : Exception
    {
        public LoadingDomainModelCorrespException(string exceptionMessage) : base(exceptionMessage) { }
    }

    /// <summary>
    /// Исключение: ошибка загрузки документа
    /// </summary>
    public class LoadingDocumentException : Exception
    {
        public LoadingDocumentException(string exceptionMessage) : base(exceptionMessage) { }
    }
    
    /// <summary>
    /// Исключение: неизвестно расширение загружаемого файла
    /// </summary>
    public class FileExtensionUnknownException : Exception
    {
        public FileExtensionUnknownException(string exceptionMessage) : base(exceptionMessage) { }
    }

    /// <summary>
    /// Исключение: ошибка загрузки типов документов
    /// </summary>
    public class LoadingDocTypesException : Exception
    {
        public LoadingDocTypesException(string exceptionMessage) : base(exceptionMessage) { }
    }

    #endregion

    /// <summary>
    /// Тип ошибки
    /// </summary>
    public enum ErrorType
    {
        /// <summary>
        /// Не найден файл редактора
        /// </summary>
        EditorFileNotFound,
        /// <summary>
        /// Не найден файл ресурсов
        /// </summary>
        ResourceFileNotFound,
        /// <summary>
        /// Ошибка при загрузке редактора (несоответствие конфигураций или DomainModel, например)      
        /// </summary>
        ErrorLoadingEditor,
        /// <summary>
        /// Файл сохраняется не в директорию проекта 
        /// (все файлы, используемые в данном проекте, должны находиться либо в папке проекта, либо во вложенной папке)
        /// </summary>
        FileNotInSubDir,
        /// <summary>
        /// Файл с таким именем уже существует
        /// </summary>
        NameAlreadyExists,
    }


    /// <summary>
    /// Инструментарий для обработки ошибок
    /// (средства извещения пользователя об ошибках, например)
    /// </summary>
    public static class ErrorsUtility
    {
        /// <summary>
        /// Сообщить пользователю об ошибке с помошью диалогового окна и залоггировать сообщение      
        /// </summary>
        /// <param name="errorType">Тип ошибки</param>
        /// <param name="Message">Текст сообщения (ошибки)</param>
        /// <param name="logger">Логгер, с помощтю которого залоггировать</param>
        public static void Error(ErrorType errorType, string Message, ILogger logger)
        {
            string fullMessage = "";
            switch (errorType)
            {
                case ErrorType.EditorFileNotFound:
                    fullMessage = "Файл проекта " + Message + "не найден ";
                    break;

                case ErrorType.ErrorLoadingEditor:
                    fullMessage = "Ошибка загрузки Файла проекта " + Message;
                    break;

                case ErrorType.FileNotInSubDir:
                    fullMessage = "Файл должен находиться внутри директории проекта ";
                    break;

                case ErrorType.NameAlreadyExists:
                    fullMessage = "В проекте уже существует документ с таким именем. " + Message;
                    break;

                case ErrorType.ResourceFileNotFound:
                    fullMessage = "Ошибка загрузки ресурса. " + Message;
                    break;
            }
            MessageBox.Show(fullMessage,"Ошибка",MessageBoxButtons.OK, MessageBoxIcon.Error);
            logger.WriteMessage(MessagePriority.Error, fullMessage);
        }

        /// <summary>
        /// Сообщить пользователю об ошибке с помошью диалогового окна и залоггировать сообщение      
        /// </summary>
        /// <param name="Message">Текст ошибки</param>
        /// <param name="logger">Логгер, с помощтю которого залоггировать</param>
        public static void Error(string Message, ILogger logger)
        { 
           MessageBox.Show(Message,"Ошибка" ,MessageBoxButtons.OK, MessageBoxIcon.Error);
           logger.WriteMessage(MessagePriority.Error, Message);
        }

        /// <summary>
        /// Создать исключение и залоггировать его, после чего прекратить работу программы
        /// </summary>
        /// <param name="errorType">Тип ошибки</param>
        /// <param name="Message">Текст сообщения (ошибки)</param>
        /// <param name="logger">Логгер, с помощтю которого залоггировать</param>
        public static void FatalError(ErrorType errorType, string Message, ILogger logger)
        {
            Exception e = null;
            switch (errorType)
            {
                case ErrorType.EditorFileNotFound:
                    e = new Exception("Файл проекта " + Message + "не найден ");
                    break;

                case ErrorType.ErrorLoadingEditor:
                    e = new Exception("Ошибка загрузки Файла проекта " + Message);
                    break;

                case ErrorType.FileNotInSubDir:
                    e = new Exception("Файл должен находиться внутри директории проекта ");
                    break;

                case ErrorType.NameAlreadyExists:
                    e = new Exception("В проекте уже существует документ с таким именем. ");
                    break;

                case ErrorType.ResourceFileNotFound:
                    e = new Exception("Ошибка загрузки ресурса. " + Message);
                    break;
            }
            ExceptionUtility.LogWith(e, logger); 
            throw e;
            Application.Exit();
        }

        /// <summary>
        /// Создать исключение и залоггировать его, после чего прекратить работу программы
        /// </summary>
        /// <param name="Message">Текст сообщения (ошибки)</param>
        /// <param name="logger">Логгер, с помощтю которого залоггировать</param>
        public static void FatalError(string Message, ILogger logger)
        {
            Exception e = new Exception(Message);     
            ExceptionUtility.LogWith(e, logger);
            throw e;
            Application.Exit();
        }

        /// <summary>
        /// Создать исключение, залоггировать его и бросить далее
        /// </summary>
        /// <param name="Message">Текст сообщения (ошибки)</param>
        /// <param name="logger">Логгер, с помощтю которого залоггировать</param>
        public static void LogAndThrowException(string Message, ILogger logger)
        {
            Exception e = new Exception(Message);     
            ExceptionUtility.LogWith(e, logger);
            throw e;
        }
    }
}
